package com.geek.javase.ch18.videodemo.reflect.singleton;

/*
 *@Date 2025/11/7
 *@Author wangpeng
 *@Description
 */
//多个线程并发，导致破坏单例
/*public class SingletonDemo1 {
    //私有的 静态的 本类实例
    private static SingletonDemo1 instance;
    //私有的构造方法
    private SingletonDemo1() {
        System.out.println(Thread.currentThread().getName());
    }
    //公开的 静态的 获得本类实例的方法
    public static SingletonDemo1 getInstance() {
        if (instance == null) {
            instance = new SingletonDemo1();
        }
        return instance;
    }
}
class Test1{
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> SingletonDemo1.getInstance()).start();
        }
    }
}*/
//线程安全的单例模式 - 懒汉式 DCL(Double Check Lock) + volatile
public class SingletonDemo1 {
    //私有的 静态的 本类实例
    //private static SingletonDemo1 instance;
    private volatile static SingletonDemo1 instance;

    //私有的构造方法
    private SingletonDemo1() {
        System.out.println(Thread.currentThread().getName());
    }
    //公开的 静态的 获得本类实例的方法
    public static SingletonDemo1 getInstance() {
        if (instance == null) {
            synchronized (SingletonDemo1.class) {
                if (instance == null) {
                    /**
                     * volatile 确保可见性、不能保证原子性、禁止指令重排
                     * 1.创建实例
                     * 2.为其分配内存空间
                     * 3.将内存空间复制给实例对象
                     * 期望：123   可能：132
                     * 解决：加锁
                     * */
                    instance = new SingletonDemo1();
                }
            }
        }
        return instance;
    }
}
/*class Test1 {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> SingletonDemo1.getInstance()).start();
        }
    }
}*/
class Test1 {
    public static void main(String[] args) {
        SingletonDemo1 s1 = SingletonDemo1.getInstance();
        SingletonDemo1 s2 = SingletonDemo1.getInstance();
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s1 == s2);
    }
}
